<?php
Junction_FileCabinet::using("Junction_Utils_IO_Exception");

/**
 * Encapsulate common file operations into a single class
 * 
 * @package junction.utils.io
 * @author Alexander Schearer <aas11@duke.edu>
 */
class Junction_Utils_IO_File implements IteratorAggregate {
	
	/**
	 * @var String
	 */
	private $_filename;
	
	/**
	 * @var array
	 */
	private $_file;
	
	public function __construct($file) {
		if (!file_exists($file) || !is_readable($file)) {
			throw new Junction_Utils_IO_Exception("File not found: " . $file);
		}
		$this->_filename = $file;
	}
	
	/**
	 * Write the passed data to the file
	 * 
	 * <p>This will overwrite any existing data in the file.
	 *
	 * @param String $data
	 * @return boolean
	 */
	public function write($data) {
		return file_put_contents($this->_filename, $data);
	}
	
	/**
	 * Write to a single specified line
	 * 
	 * @param int $line
	 * @param String $data
	 * @return boolean
	 */
	public function writeLine($line, $data) {
		$lines = $this->getFile();
		$lines[$line] = $data;
		return file_put_contents($this->_filename, $lines);
	}
	
	/**
	 * Read the entire file and return its contents
	 *
	 * @return String
	 */
	public function read() {
		return file_get_contents($this->_filename);
	}
	
	/**
	 * Read a given line from the file
	 * 
	 * <p>Note that this still must read the entire file before it
	 * once before it can return any value.  Also note that it will
	 * only have to read the file the first time this method is 
	 * called, as the contents will be kept in memory afterwards.
	 * 
	 * @param int $line
	 * @return String
	 */
	public function readLine($line) {
		$lines = $this->getFile();
		return $lines[$line];
	}
	
	public function getIterator() {
		return new ArrayIterator($this->getFile());
	}
	
	/**
	 * Read the entire file into array once
	 * 
	 */
	private function getFile() {
		if (!isset($this->_file)) {
			$this->_file = file($this->_filename);
		}
		return $this->_file;
	}
}
?>